home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 4 / QRZ Ham Radio Callsign Database - Volume 4.iso / files / tcpip / amiga / asrc29p.lha / pppcmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-29  |  21.1 KB  |  863 lines

  1. /*
  2.  *  PPPCMD.C    -- PPP related user commands
  3.  *
  4.  *    12-89    -- Katie Stevens (dkstevens@ucdavis.edu)
  5.  *           UC Davis, Computing Services
  6.  *    PPP.07    04-90    [ks] new storage for peer addr for IPCP
  7.  *    PPP.08  05-90    [ks] improve PPP trace reporting
  8.  *    PPP.09    05-90    [ks] add commands to set PPP Auth protocol
  9.  *                 (UPAP server) and UPAP peerID (UPAP client)
  10.  *    PPP.10    6-90    [ks] improve keybd input of UPAP password
  11.  *                 make ppp open/close/reset work properly
  12.  *                 add peer IP lookup pool
  13.  *    PPP.13    8-90    [ks] report PPP open timestamp with stats
  14.  *    PPP.14    8-90    [ks] change UPAP to PAP for consistency with RFC1172
  15.  *                 add RLSD physical link up/down handling
  16.  *                 add autobaud handling to set link speed
  17.  *                 make LCP/IPCP timeout configurable
  18.  *    PPP.15    09-90    [ks] update to KA9Q NOS v900828
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <time.h>
  23. #include "global.h"
  24. #include "mbuf.h"
  25. #include "iface.h"
  26. #include "timer.h"
  27. #include "amiga/asy.h"
  28. #include "slcompre.h"
  29. #include "ppp.h"
  30. #include "slip.h"
  31. #include "commands.h"
  32. #include "netuser.h"
  33. /*#include "internet.h"*/
  34. #include "cmdparse.h"
  35. #include "config.h"
  36.  
  37. extern char Badhost[];
  38.  
  39. int16 ppptrace = 0;
  40. int16 Npool = 0;        /* Number of pools for PPP interfaces */
  41.  
  42. #ifdef notdef /*MUXASY*/
  43. struct ipcppool PPPpool[ASY_MAX*PORTS_PER_MUX];    /* For pooling peer IP addrs */
  44. #else
  45. struct ipcppool PPPpool[ASY_MAX];        /* For pooling peer IP addrs */
  46. #endif
  47.  
  48. static int dopppaccomp __ARGS((int argc, char *argv[], void *p));
  49. static int dopppactive __ARGS((int argc, char *argv[], void *p));
  50. static int dopppauth __ARGS((int argc, char *argv[], void *p));
  51. static int dopppclose __ARGS((int argc, char *argv[], void *p));
  52. static int dopppctlmap __ARGS((int argc, char *argv[], void *p));
  53. static int dopppmru __ARGS((int argc, char *argv[], void *p));
  54. static int dopppipcomp __ARGS((int argc, char *argv[], void *p));
  55. static int doppppassive __ARGS((int argc, char *argv[], void *p));
  56. static int doppppeer __ARGS((int argc, char *argv[], void *p));
  57. static int doppppool __ARGS((int argc, char *argv[], void *p));
  58. static int dopppprotcomp __ARGS((int argc, char *argv[], void *p));
  59. static int dopppreset __ARGS((int argc, char *argv[], void *p));
  60. static int dopppstat __ARGS((int argc, char *argv[], void *p));
  61. static int doppptrace __ARGS((int argc, char *argv[], void *p));
  62. static int doppptimeout __ARGS((int argc, char *argv[], void *p));
  63. static int dopapuser __ARGS((int argc, char *argv[], void *p));
  64.  
  65. static void genstat __ARGS((struct slip *sp));
  66. static void pppstat __ARGS((struct slip *sp));
  67. static void lcpstat __ARGS((struct lcpctl *lcpiop));
  68. static void ipcpstat __ARGS((struct ipcpctl *ipcpiop));
  69. static struct iface *ppplookup __ARGS((char *ifname));
  70. static void dumppool __ARGS(());
  71. static char *uptime __ARGS((long first, long second));
  72.  
  73. static char VJtcphc[] = "Van Jacobson TCP header compression";
  74.  
  75. /* "ppp" subcommands */
  76. static struct cmds Pppcmds[] = {
  77.     "accompr",    dopppaccomp,    0,    2,
  78.         "ppp accompr <iface> <int>",
  79.     "activeopen",    dopppactive,    0,    2,
  80.         "ppp activeopen <iface>",
  81.     "authprot",    dopppauth,    0,    2,
  82.         "ppp authprot <authtype>",
  83.     "close",    dopppclose,    0,    2,
  84.         "ppp close <iface>",
  85.     "ctlmap",    dopppctlmap,    0,    2,
  86.         "ppp ctlmap <iface> <int>",
  87.     "ipcompr",    dopppipcomp,    0,    2,
  88.         "ppp ipcompr <iface> <comprtype>",
  89.     "mru",        dopppmru,    0,    2,
  90.         "ppp mru <iface> <int>",
  91.     "passiveopen",    doppppassive,    0,    2,
  92.         "ppp passiveopen <iface>",
  93.     "peeraddr",    doppppeer,    0,    2,
  94.         "ppp peeraddr <iface> <addr>",
  95.     "peerid",    dopapuser,    0,    2,
  96.         "ppp peerid <iface> <peer ID code>",
  97.     "pooladdr",    doppppool,    0,    1,
  98.         "ppp pooladdr <addr>:<# addr in pool> [ <iface> ... ]",
  99.     "protcompr",    dopppprotcomp,    0,    2,
  100.         "ppp protcompr <iface> <int>",
  101.     "reset",    dopppreset,    0,    2,
  102.         "ppp reset <iface>",
  103.     "status",    dopppstat,    0,    0,    NULLCHAR,
  104.     "timeout",    doppptimeout,    0,    2,
  105.         "ppp timeout <iface> <#sec>",
  106.     "trace",    doppptrace,    0,    0,    NULLCHAR,
  107.     NULLCHAR,
  108. };
  109.  
  110. static char *PPPStatus[] = {
  111.     "physical layer down",
  112.     "waiting for link speed assignment message",
  113.     "Closed",
  114.     "waiting for LCP negotiation",
  115.     "waiting for PAP verfication",
  116.     "waiting for IPCP negotiation",
  117.     "Open"
  118. };
  119. static char *LCPStatus[] = {
  120.     "Closed",
  121.     "Listen; waiting for remote host to attempt open",
  122.     "Req Sent: Attempting to start configuration exchange",
  123.     "Ack Rcvd: Remote host accepted our request; waiting for remote request",
  124.     "Ack Sent: Waiting for reply to our request; accepted remote request",
  125.     "Open; configuration negotiation complete",
  126.     "Terminate request sent to remote host"
  127. };
  128.  
  129. /****************************************************************************/
  130.  
  131. int
  132. dopppcontrol(argc,argv,p)
  133. int argc;
  134. char *argv[];
  135. void *p;
  136. {
  137.     return subcmd(Pppcmds,argc,argv,p);
  138. }
  139.  
  140. /****************************************************************************/
  141.  
  142. /* Initiate active open on a PPP interface */
  143. static int
  144. dopppactive(argc,argv,p)
  145. int argc;
  146. char *argv[];
  147. void *p;
  148. {
  149.     struct iface *ifp;
  150.     struct pppctl *pppiop;
  151.     struct lcpctl *lcpiop;
  152.  
  153.     /* Look for the PPP interface */
  154.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  155.         return -1;
  156.  
  157.     /* Start LCP configuration negotiation on interface */
  158.     pppiop = Slip[ifp->xdev].pppio;
  159.     lcpiop = &(pppiop->lcpio);
  160.     lcpiop->active = 1;
  161.     if ((pppiop->state == PPP_PL_DOWN) || (pppiop->state == PPP_AUTOBAUD))
  162.         return 0;
  163.     else
  164.         return(lcp_start(&Slip[ifp->xdev]));
  165. }
  166.  
  167. /* Close connection on PPP interface */
  168. static int
  169. dopppclose(argc,argv,p)
  170. int argc;
  171. char *argv[];
  172. void *p;
  173. {
  174.     struct iface *ifp;
  175.  
  176.     /* Look for the PPP interface */
  177.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  178.         return -1;
  179.  
  180.     /* Close PPP connection */
  181.     return(ppp_close(&Slip[ifp->xdev],1));
  182. }
  183.  
  184. /* Set PPP interface to passive open; will revert to LISTEN on next close */
  185. static int
  186. doppppassive(argc,argv,p)
  187. int argc;
  188. char *argv[];
  189. void *p;
  190. {
  191.     struct iface *ifp;
  192.     struct pppctl *pppiop;
  193.     struct lcpctl *lcpiop;
  194.  
  195.     /* Look for the PPP interface */
  196.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  197.         return -1;
  198.  
  199.     /* Start LCP configuration negotiation on interface */
  200.     pppiop = Slip[ifp->xdev].pppio;
  201.     lcpiop = &(pppiop->lcpio);
  202.     lcpiop->active = 0;
  203.     return 0;
  204. }
  205.  
  206. /* Close and reopen connection on PPP interface */
  207. static int
  208. dopppreset(argc,argv,p)
  209. int argc;
  210. char *argv[];
  211. void *p;
  212. {
  213.     struct iface *ifp;
  214.     struct slip *sp;
  215.     struct pppctl *pp;
  216.     struct slcompress *slp;
  217.  
  218.     /* Look for the PPP interface */
  219.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  220.         return -1;
  221.     sp = &Slip[ifp->xdev];
  222.     pp = sp->pppio;
  223.  
  224.     /* Close PPP connection */
  225.     ppp_close(&Slip[ifp->xdev],0);
  226.  
  227. #ifndef PPP_NO_STATS
  228.     /* Zero PPP packet counters */
  229.     pp->sndpkt = 0L;        /* # packets sent on PPP interface */
  230.     pp->snderr = 0;            /* # pkts with PPP error on send */
  231.     pp->rcvpkt = 0L;        /* # packets rcvd on PPP interface */
  232.     pp->rcverr = 0;            /* # pkts with error */
  233.     pp->csumerr = 0;        /* # rcv pkts with bad PPP checksum */
  234.  
  235.     pp->sndlcp = 0;            /* # LCP packets sent */
  236.     pp->sndpap = 0;            /* # PAP packets sent */
  237.     pp->sndipcp = 0;        /* # IPCP packets sent */
  238.     pp->sndip = 0L;            /* # IP packets sent */
  239.     pp->rcvlcp = 0;            /* # LCP packets received */
  240.     pp->rcvpap = 0;            /* # PAP packets received */
  241.     pp->rcvipcp = 0;        /* # IPCP packets received */
  242.     pp->rcvip = 0L;            /* # IP packets received */
  243.     pp->rcvunk = 0;            /* # unknown packets received */
  244. #endif
  245.  
  246. #ifndef SL_NO_STATS
  247.     slp = sp->slcomp;
  248.     slp->sls_nontcp = 0L;        /* outbound non-TCP packets */
  249.     slp->sls_asistcp = 0L;        /* outbound TCP packets */
  250.     slp->sls_compressed = 0L;    /* outbound compressed packets */
  251.     slp->sls_uncompressed = 0L;    /* outbound uncompressed packets */
  252.     slp->sls_searches = 0L;        /* searches for connection state */
  253.     slp->sls_misses = 0L;        /* times couldn't find conn. state */
  254.     slp->sls_nontcpin = 0L;        /* inbound non-TCP packets */
  255.     slp->sls_tcpin = 0L;        /* inbound TCP packets */
  256.     slp->sls_uncompressedin = 0L;    /* inbound uncompressed packets */
  257.     slp->sls_compressedin = 0L;    /* inbound compressed packets */
  258.     slp->sls_errorin = 0L;        /* inbound unknown type packets */
  259.     slp->sls_tossed = 0L;        /* inbound tossed because of error */
  260. #endif
  261.  
  262.     /* Always restart as active open when PPP reset */
  263.     pp->lcpio.active = 1;
  264.     tprintf("Attempting to reopen PPP interface  %s\n",ifp->name);
  265.     return(lcp_start(&Slip[ifp->xdev]));
  266. }
  267.  
  268. /*******************************************/
  269.  
  270. /* Set Address/Control Compression for a PPP interface */
  271. static int
  272. dopppaccomp(argc,argv,p)
  273. int argc;
  274. char *argv[];
  275. void *p;
  276. {
  277.     struct iface *ifp;
  278.     struct pppctl *pppiop;
  279.     struct lcpctl *lcpiop;
  280.     struct lcpparm *localp;
  281.  
  282.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  283.         return -1;
  284.     --argc;++argv;
  285.  
  286.     pppiop = Slip[ifp->xdev].pppio;
  287.     lcpiop = &(pppiop->lcpio);
  288.     localp = &(lcpiop->initparm);
  289.     localp->neg_ac_compress = 1;
  290.     return setbool(&(localp->ac_compress),
  291.             "Addr/Ctl Field Compression",argc,argv);
  292. }
  293.  
  294. /* Set authentication type for PPP interface */
  295. static int
  296. dopppauth(argc,argv,p)
  297. int argc;
  298. char *argv[];
  299. void *p;
  300. {
  301.     struct iface *ifp;
  302.     struct pppctl *pppiop;
  303.     struct lcpctl *lcpiop;
  304.     struct lcpparm *localp;
  305.  
  306.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  307.         return -1;
  308.  
  309.     pppiop = Slip[ifp->xdev].pppio;
  310.     lcpiop = &(pppiop->lcpio);
  311.     localp = &(lcpiop->initparm);
  312.     if (argc < 3) {
  313.         tprintf("%s\n",((localp->auth_type == PAP_AUTH_TYPE) ? "PAP" : "None"));
  314.     } else if ((strnicmp("pap",argv[2],2) == 0)
  315.             || ((int16)strtol(argv[2],NULLCHARP,0)==PAP_AUTH_TYPE)) {
  316.         localp->neg_auth_type = 1;
  317.         localp->auth_type = PAP_AUTH_TYPE;
  318.     } else if ((stricmp("none",argv[2]) == 0)
  319.             || ((int16)strtol(argv[2],NULLCHARP,0) == 0)) {
  320.         localp->neg_auth_type = 0;
  321.         localp->auth_type = DEF_AUTH_TYPE;
  322.     } else {
  323.         tprintf("unknown Authentication Protocol type; command ignored\n");
  324.         return 1;
  325.     }
  326.     return 0;
  327. }
  328.  
  329. /* Set Async Control Map for a PPP interface */
  330. static int
  331. dopppctlmap(argc,argv,p)
  332. int argc;
  333. char *argv[];
  334. void *p;
  335. {
  336.     long lx;
  337.     struct iface *ifp;
  338.     struct pppctl *pppiop;
  339.     struct lcpctl *lcpiop;
  340.     struct lcpparm *localp;
  341.  
  342.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  343.         return -1;
  344.  
  345.     pppiop = Slip[ifp->xdev].pppio;
  346.     lcpiop = &(pppiop->lcpio);
  347.     localp = &(lcpiop->initparm);
  348.     if (argc < 3) {
  349.         tprintf("0x%08lx\n",localp->ctl_map);
  350.     } else {
  351.         lx = strtol(argv[2], NULLCHARP, 0);
  352.         localp->neg_ctl_map = 1;
  353.         localp->ctl_map = lx;
  354.     }
  355.     return 0;
  356. }
  357.  
  358. /* Set preferred Maximum Receive Unit for a PPP interface */
  359. static int
  360. dopppmru(argc,argv,p)
  361. int argc;
  362. char *argv[];
  363. void *p;
  364. {
  365.     int x;
  366.     struct iface *ifp;
  367.     struct pppctl *pppiop;
  368.     struct lcpctl *lcpiop;
  369.     struct lcpparm *localp;
  370.  
  371.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  372.         return -1;
  373.  
  374.     pppiop = Slip[ifp->xdev].pppio;
  375.     lcpiop = &(pppiop->lcpio);
  376.     localp = &(lcpiop->initparm);
  377.     if (argc < 3) {
  378.         tprintf("%d\n",localp->mru);
  379.     } else {
  380.         x = atoi(argv[2]);
  381.         if ((x < MIN_MRU)||(x > DEF_MRU)) {
  382.             tprintf("Command rejected; MRU out of range: Min MRU: %d  Max MRU: %d\n",
  383.                 MIN_MRU,DEF_MRU);
  384.             return -1;
  385.         } else {
  386.             localp->neg_mru = 1;
  387.             localp->mru = x;
  388.         }
  389.     }
  390.     return 0;
  391. }
  392.  
  393. /* Set Protocol Compression for a PPP interface */
  394. static int
  395. dopppprotcomp(argc,argv,p)
  396. int argc;
  397. char *argv[];
  398. void *p;
  399. {
  400.     struct iface *ifp;
  401.     struct pppctl *pppiop;
  402.     struct lcpctl *lcpiop;
  403.     struct lcpparm *localp;
  404.  
  405.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  406.         return -1;
  407.     --argc;++argv;
  408.  
  409.     pppiop = Slip[ifp->xdev].pppio;
  410.     lcpiop = &(pppiop->lcpio);
  411.     localp = &(lcpiop->initparm);
  412.     localp->neg_prot_compress = 1;
  413.     return setbool(&(localp->prot_compress),
  414.             "Protocol Field Compression",argc,argv);
  415. }
  416.  
  417. /* Set timeout interval when waiting for response from remote peer */
  418. static int
  419. doppptimeout(argc,argv,p)
  420. int argc;
  421. char *argv[];
  422. void *p;
  423. {
  424.     int x;
  425.     struct iface *ifp;
  426.     struct pppctl *pppiop;
  427.     struct lcpctl *lcpiop;
  428.     struct ipcpctl *ipcpiop;
  429.     struct timer *t;
  430.  
  431.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  432.         return -1;
  433.  
  434.     pppiop = Slip[ifp->xdev].pppio;
  435.     lcpiop = &(pppiop->lcpio);
  436.     t = &(lcpiop->lcp_tm);
  437.     if (argc < 3) {
  438.         tprintf("%d\n",(t->start/(1000L/MSPTICK)));
  439.     } else {
  440.         x = atoi(argv[2]);
  441.         if (x <= 0) {
  442.             tprintf("Command rejected; timeout value must be > 0\n");
  443.             return -1;
  444.         } else {
  445.             t->start = x*(1000L/MSPTICK);
  446.             ipcpiop = &(pppiop->ipcpio);
  447.             t = &(ipcpiop->ipcp_tm);
  448.             t->start = x*(1000L/MSPTICK);
  449.         }
  450.     }
  451.     return 0;
  452. }
  453.  
  454. /* Set peer ID string to send with PAP AUTH_REQ */
  455. static int
  456. dopapuser(argc,argv,p)
  457. int argc;
  458. char *argv[];
  459. void *p;
  460. {
  461.     struct iface *ifp;
  462.     struct pppctl *pppiop;
  463.     struct lcpctl *lcpiop;
  464.  
  465.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  466.         return -1;
  467.  
  468.     pppiop = Slip[ifp->xdev].pppio;
  469.     lcpiop = &(pppiop->lcpio);
  470.     if (argc < 3) {
  471.         tprintf("%s\n",((lcpiop->pap_user==NULLCHAR)?"None":lcpiop->pap_user));
  472.     } else if (strnicmp("none",argv[2],2) == 0) {
  473.         if (lcpiop->pap_user != NULLCHAR)
  474.             free(lcpiop->pap_user);
  475.     } else {
  476.         if (lcpiop->pap_user != NULLCHAR)
  477.             free(lcpiop->pap_user);
  478.         if (lcpiop->pap_pass != NULLCHAR)
  479.             free(lcpiop->pap_pass);
  480.         lcpiop->pap_user = mallocw(strlen(argv[2])+1);
  481.         strcpy(lcpiop->pap_user,argv[2]);
  482.         pap_getpass(&Slip[ifp->xdev],0);
  483.     }
  484.     return 0;
  485. }
  486.  
  487. /*******************************************/
  488.  
  489. /* Set IP compression type for PPP interface */
  490. static int dopppipcomp(argc,argv,p)
  491. int argc;
  492. char *argv[];
  493. void *p;
  494. {
  495.     struct iface *ifp;
  496.     struct pppctl *pppiop;
  497.     struct ipcpctl *ipcpiop;
  498.  
  499.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  500.         return -1;
  501.  
  502.     pppiop = Slip[ifp->xdev].pppio;
  503.     ipcpiop = &(pppiop->ipcpio);
  504.     if (argc < 3) {
  505.         tprintf("%s", VJtcphc);
  506.         switch (ipcpiop->ip_compr_type) {
  507.         case IPCP_OVJCOMP:
  508.             tprintf(" enabled (OLD)\n");
  509.             break;
  510.         case IPCP_NVJCOMP:
  511.             tprintf(" enabled (NEW)\n");
  512.             break;
  513.         default:
  514.             tprintf(" disabled\n");
  515.         }
  516.     } else if ((strnicmp("vjold",argv[2],5) == 0)
  517.             || ((int16)strtol(argv[2],NULLCHARP,0) == IPCP_OVJCOMP)) {
  518.         ipcpiop->neg_ip_compr = 1;
  519.         ipcpiop->ip_compr_type = IPCP_OVJCOMP;
  520.     } else if ((strnicmp("vjnew",argv[2],5) == 0)
  521.             || ((int16)strtol(argv[2],NULLCHARP,0) == IPCP_NVJCOMP)) {
  522.         ipcpiop->neg_ip_compr = 1;
  523.         ipcpiop->ip_compr_type = IPCP_NVJCOMP;
  524.     } else if ((int16)strtol(argv[2],NULLCHARP,0) == 0) {
  525.         ipcpiop->neg_ip_compr = 1;
  526.         ipcpiop->ip_compr_type = 0;
  527.     } else {
  528.         tprintf("unknown IP compression type; command ignored\n");
  529.         return 1;
  530.     }
  531.     return 0;
  532. }
  533.  
  534. /* Set peer address for PPP interface */
  535. static int
  536. doppppeer(argc,argv,p)
  537. int argc;
  538. char *argv[];
  539. void *p;
  540. {
  541.     int32 x32;
  542.     struct iface *ifp;
  543.     struct pppctl *pppiop;
  544.     struct ipcpctl *ipcpiop;
  545.  
  546.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  547.         return -1;
  548.  
  549.     pppiop = Slip[ifp->xdev].pppio;
  550.     ipcpiop = &(pppiop->ipcpio);
  551.     if (argc < 3) {
  552.         tprintf("%s\n",inet_ntoa(ipcpiop->peer_addr));
  553.     } else if ((x32 = resolve(argv[2])) == 0L) {
  554.         tprintf(Badhost,argv[2]);
  555.         return 1;
  556.     } else {
  557.         ipcpiop->peer_addr = x32;
  558.     }
  559.     return 0;
  560. }
  561.  
  562. /* Set a pool of peer addresses for PPP interface */
  563. static int
  564. doppppool(argc,argv,p)
  565. int argc;
  566. char *argv[];
  567. void *p;
  568. {
  569.     int pool;
  570.     int pool_cnt;
  571.     char *bitp;
  572.     int32 pool_addr;
  573.     struct ipcppool *poolp;
  574.     struct iface *ifp;
  575.     struct pppctl *pppiop;
  576.  
  577.     if (argc < 2) {
  578.         dumppool();
  579.         return 0;
  580.     }
  581.  
  582.     if (Npool > ASY_MAX) {
  583.         tprintf("Too many PPP address pools -- command rejected\n");
  584.         return -1;
  585.     }
  586.  
  587.     /* Need at least one IP address for the pool */
  588.     if((pool_addr = resolve(argv[1])) == 0){
  589.         tprintf("Must specify an IP address pool\n");
  590.         return -1;
  591.     }
  592.     /* May specify a consecutive range of addresses; otherwise assume 1 */
  593.     if((bitp = strchr(argv[1],':')) != NULLCHAR){
  594.         bitp++;
  595.         pool_cnt = atoi(bitp);
  596.     } else
  597.         pool_cnt = 1;
  598.     if (pool_cnt < 0) {
  599.         tprintf("Unreasonable address range  --  command rejected\n");
  600.         return -1;
  601.     }
  602.  
  603.     if (argc < 3) {
  604.         printf("Must specify a PPP interface\n");
  605.         return -1;
  606.     }
  607.  
  608.     pool = Npool++;
  609.     poolp = &(PPPpool[pool]);
  610.     poolp->peer_min = pool_addr;
  611.     poolp->peer_max = pool_addr + pool_cnt - 1;
  612.     poolp->peer_next = pool_addr;
  613.  
  614.     argc -= 2;argv++;
  615.     while (argc--) {
  616.         argv++;
  617.         if ((ifp = ppplookup(*argv)) == NULLIF)
  618.             continue;
  619.         pppiop = Slip[ifp->xdev].pppio;
  620.         pppiop->ipcpio.peer_pool = &(PPPpool[pool]);
  621.     }
  622.     return 0;
  623. }
  624.  
  625. /****************************************************************************/
  626.  
  627. static int
  628. doppptrace(argc,argv,p)
  629. int argc;
  630. char *argv[];
  631. void *p;
  632. {
  633.     return setshort(&ppptrace,"PPP tracing",argc,argv);
  634. }
  635.  
  636. /****************************************************************************/
  637.  
  638. static int
  639. dopppstat(argc,argv,p)
  640. int argc;
  641. char *argv[];
  642. void *p;
  643. {
  644.     register struct slip *sp;
  645.     struct iface *ifp;
  646.  
  647.     if (argc < 2) {
  648.         for (sp = Slip;sp < &Slip[Nasy];sp++) {
  649.             if (sp->type != TYPE_PPP)
  650.                 continue;
  651.             genstat(sp);
  652.         }
  653.     } else {
  654.         if ((ifp = ppplookup(argv[1])) == NULLIF)
  655.             return -1;
  656.         sp = &Slip[ifp->xdev];
  657.         genstat(sp);
  658.         pppstat(sp);
  659.         lcpstat(&(sp->pppio->lcpio));
  660.         ipcpstat(&(sp->pppio->ipcpio));
  661.     }
  662.     return 0;
  663. }
  664.  
  665. static void
  666. genstat(sp)
  667. struct slip *sp;
  668. {
  669.     register struct pppctl *pp;
  670.  
  671.     pp = sp->pppio;
  672.     tprintf("%s:\t",sp->iface->name);
  673.     tprintf("SndPkt: %ld  SndErr: %d  RcvPkt: %ld  RcvErr: %d  ChksumErr: %d\n",
  674.         pp->sndpkt,pp->snderr,pp->rcvpkt,pp->rcverr,pp->csumerr);
  675.     return;
  676. }
  677.  
  678. static void
  679. pppstat(sp)
  680. struct slip *sp;
  681. {
  682.     register struct pppctl *pp;
  683.     register struct slcompress *scp;
  684.  
  685.     pp = sp->pppio;
  686.     scp = sp->slcomp;
  687.     tprintf("\tOverall PPP state: %s",
  688.         PPPStatus[pp->state]);
  689.     if (pp->state == PPP_OPEN) {
  690.         tprintf("   (open for %s)\n",uptime(pp->upsince,time(0L)));
  691.     } else {
  692.         tprintf("\n");
  693.     }
  694.     tprintf("\t    SndIP: %ld  SndLCP: %d  SndPAP: %d  SndIPCP: %d\n",
  695.         pp->sndip,pp->sndlcp,pp->sndpap,pp->sndipcp);
  696.     if (sp->escaped & PPP_XMT_VJCOMPR) {
  697.         tprintf("\t      (IP) NotTCP: %ld  AsIsTCP: %ld  CmpTCP: %ld  UncmpTCP: %ld\n",
  698.             scp->sls_nontcp,scp->sls_asistcp,scp->sls_compressed,scp->sls_uncompressed);
  699.     }
  700.     tprintf("\t    RcvIP: %ld  RcvLCP: %d  RcvPAP: %d  RcvIPCP: %d  RcvUnknown: %d\n",
  701.         pp->rcvip,pp->rcvlcp,pp->rcvpap,pp->rcvipcp,pp->rcvunk);
  702.     if (sp->escaped & PPP_RCV_VJCOMPR) {
  703.         tprintf("\t      (IP) NotTCP: %ld  AsIsTCP: %ld  CmpTCP: %ld  UncmpTCP: %ld\n",
  704.             scp->sls_nontcpin,scp->sls_tcpin,scp->sls_compressedin,scp->sls_uncompressedin);
  705.         tprintf("\t           Unknown: %ld  CmpError: %ld\n",
  706.             scp->sls_errorin,scp->sls_tossed);
  707.     }
  708.     return;
  709. }
  710.  
  711. static void
  712. lcpstat(lcpiop)
  713. struct lcpctl *lcpiop;
  714. {
  715.     struct lcpparm *localp, *remotep;
  716.  
  717.     localp = &(lcpiop->lclparm);
  718.     remotep = &(lcpiop->remparm);
  719.  
  720.     tprintf("\tLCP state: %s\n",LCPStatus[lcpiop->lcp_state]);
  721.     tprintf("\t\t\t\tLocal options\tRemote options\n");
  722.     tprintf("\t    MRU:\t\t%d\t\t%d\n",
  723.         localp->mru,remotep->mru);
  724.     tprintf("\t    Ctl Map:\t\t0x%08lx\t0x%08lx\n",
  725.         localp->ctl_map,remotep->ctl_map);
  726.     tprintf("\t    Auth Prot:\t\t%s\t\t%s\n",
  727.         ((localp->auth_type == PAP_AUTH_TYPE) ? "PAP" : "None"),
  728.         ((remotep->auth_type == PAP_AUTH_TYPE) ? "PAP" : "None"));
  729.     tprintf("\t    Protocol Compr:\t%s\t\t%s\n",
  730.         (localp->prot_compress ? "ON" : "OFF"),
  731.         (remotep->prot_compress ? "ON" : "OFF"));
  732.     tprintf("\t    Addr/Ctl Compr:\t%s\t\t%s\n",
  733.         (localp->ac_compress ? "ON" : "OFF"),
  734.         (remotep->ac_compress ? "ON" : "OFF"));
  735. }
  736.  
  737. static void
  738. ipcpstat(ipcpiop)
  739. struct ipcpctl *ipcpiop;
  740. {
  741.     tprintf("\tIPCP state: %s\n",LCPStatus[ipcpiop->ipcp_state]);
  742.     tprintf("\t    IPCP local IP address:\t%s\n",
  743.         inet_ntoa(ipcpiop->attempt_src));
  744.     tprintf("\t    IPCP remote IP address:\t%s\n",
  745.         inet_ntoa(ipcpiop->attempt_dest));
  746.     tprintf("\t    Rcv: %s", VJtcphc);
  747.     switch (ipcpiop->lcl_ip_compr) {
  748.     case IPCP_OVJCOMP:
  749.         tprintf(" enabled (OLD)\n");
  750.         break;
  751.     case IPCP_NVJCOMP:
  752.         tprintf(" enabled (NEW)\n");
  753.         break;
  754.     default:
  755.         tprintf(" disabled\n");
  756.     }
  757.     tprintf("\t    Snd: %s", VJtcphc);
  758.     switch (ipcpiop->rem_ip_compr) {
  759.     case IPCP_OVJCOMP:
  760.         tprintf(" enabled (OLD)\n");
  761.         break;
  762.     case IPCP_NVJCOMP:
  763.         tprintf(" enabled (NEW)\n");
  764.         break;
  765.     default:
  766.         tprintf(" disabled\n");
  767.     }
  768.     return;
  769. }
  770.  
  771. /****************************************************************************/
  772.  
  773. static void
  774. dumppool()
  775. {
  776.     struct iface *ifp;
  777.     struct pppctl *pppiop;
  778.     struct ipcppool *poolp;
  779.  
  780.     tprintf("Interface        Pool Base/Count\tNext Address\n");
  781.     for (ifp=Ifaces; ifp != NULLIF; ifp = ifp->next) {
  782.         if ((Slip[ifp->xdev].iface == ifp) &&
  783.             (Slip[ifp->xdev].type == TYPE_PPP)) {
  784.             pppiop = Slip[ifp->xdev].pppio;
  785.             poolp = pppiop->ipcpio.peer_pool;
  786.             if (poolp == NULLPOOL)
  787.                 continue;
  788.             tprintf("%-11s%19s/%-2d",
  789.                 ifp->name,inet_ntoa(poolp->peer_min),
  790.                 (poolp->peer_max - poolp->peer_min + 1));
  791.             tprintf("\t%s\n",inet_ntoa(poolp->peer_next));
  792.         }
  793.     }
  794.     return;
  795. }
  796.  
  797. static struct iface *
  798. ppplookup(ifname)
  799. char *ifname;
  800. {
  801.     struct iface *ifp;
  802.  
  803.     for (ifp=Ifaces;ifp != NULLIF;ifp = ifp->next) {
  804.         if (!strcmp(ifname,ifp->name))
  805.             break;
  806.     }
  807.     if (ifp == NULLIF) {
  808.         tprintf(Badinterface,ifname);
  809.         return(NULLIF);
  810.     } else if (ifp->type != TYPE_PPP) {
  811.         tprintf("Interface %s not a PPP interface\n",ifp->name);
  812.         return(NULLIF);
  813.     } else {
  814.         return(ifp);
  815.     }
  816. }
  817.  
  818.  
  819. /* Break a time differential, measured in seconds, into weeks, days      */
  820. /* hours, minutes, and seconds. Store ASCII description in static buffer */
  821. #define SECS_MIN    60L
  822. #define SECS_HR        3600L
  823. #define SECS_DAY    86400L
  824. #define SECS_WEEK    604800L
  825.  
  826. static char utbuf[128];
  827.  
  828. static char *
  829. uptime(first, second)
  830. long first;
  831. long second;
  832. {
  833.     int found = 0;
  834.     long diff;
  835.     long part;
  836.  
  837.     utbuf[0] = '\0';
  838.     diff = second - first;
  839.     if ((diff > SECS_DAY)||(found)) {
  840.         part = diff / SECS_DAY;
  841.         sprintf(&(utbuf[strlen(utbuf)]),
  842.             "%ld day%s ",part,((part==1)?",":"s,"));
  843.         diff -= (part * SECS_DAY);
  844.         found = 100;
  845.     }
  846.     if ((diff > SECS_HR)||(found)) {
  847.         part = diff / SECS_HR;
  848.         sprintf(&(utbuf[strlen(utbuf)]),
  849.             "%ld hr%s ",part,((part==1)?",":"s,"));
  850.         diff -= (part * SECS_HR);
  851.         ++found;
  852.     }
  853.     if ((diff > SECS_MIN)||(found)) {
  854.         part = diff / SECS_MIN;
  855.         sprintf(&(utbuf[strlen(utbuf)]),"%ld mi%s",part,
  856.             ((found < 100)?"n, ":"n"));
  857.         diff -= (part * SECS_MIN);
  858.     }
  859.     if (found < 100)
  860.         sprintf(&(utbuf[strlen(utbuf)]),"%ld sec",diff);
  861.     return(utbuf);
  862. }
  863.